package com.apesay.agent;

import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

/**
 * ClassName:JVMClassLoader
 * Reason:	 
 * Date:     2017/11/10 16:40
 *
 * @author sid
 */
public class JVMClassLoader extends ClassLoader {

    // used by toClass().
    private static Method defineClass1;

    static {
        try {
            AccessController.doPrivileged(new PrivilegedExceptionAction(){
                public Object run() throws Exception{
                    Class cl = Class.forName("java.lang.ClassLoader");
                    defineClass1 = cl.getDeclaredMethod("defineClass",
                            new Class[] { String.class, byte[].class,
                                    int.class, int.class });
                    return null;
                }
            });
        }
        catch (PrivilegedActionException pae) {
            throw new RuntimeException("cannot initialize ClassPool", pae.getException());
        }
    }
    
    public Object defineLoadingClass(String name, byte[] b) throws ASMCompileException {
        Object[] args = new Object[] { name, b, new Integer(0), new Integer(b.length)};
        return toClass2(defineClass1,Thread.currentThread().getContextClassLoader(),args);
    }

    private static synchronized Object toClass2(Method method, ClassLoader loader, Object[] args) throws ASMCompileException {
        method.setAccessible(true);
        try {
            return method.invoke(loader, args);
        }catch (Exception e){
            e.printStackTrace();
            throw new ASMCompileException();
        }
        finally {
            method.setAccessible(false);
        }
    }


}
